package com.oauth.google.server.service;

import java.net.URL;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.authn.oauth.OAuthSigner;
import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.media.MediaFeed;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.VideoFeed;
import com.oauth.google.client.beans.youtube.YouTubeVideo;
import com.oauth.google.server.conf.GoogleOAuthConfig;
import com.oauth.google.server.conf.YoutubeInfoBean;
import com.oauth.google.server.constants.GoogleServiceType;
import com.oauth.google.server.shared.GoogleYoutubeUtil;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.global.beans.OAuthAccessToken;

@Service
public class YoutubeOAuthServiceImpl extends AbstractGoogleOAuthService implements
		YoutubeOAuthService {

	private GoogleOAuthHelper mOAuthHelper;
	private OAuthSigner mSigner;
	@Autowired
	private ApplicationService applicationService;

	@Autowired
	@Qualifier("youtubeConfig")
	private GoogleOAuthConfig oAuthConfigBean;

	@Autowired
	YoutubeInfoBean youtubeInfoBean;

	@PostConstruct
	public void initialise() {
		mSigner = new OAuthHmacSha1Signer();
		mOAuthHelper = new GoogleOAuthHelper(mSigner);
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	public void setOAuthConfigBean(GoogleOAuthConfig pOAuthConfigBean) {
		oAuthConfigBean = pOAuthConfigBean;
	}

	private YouTubeService getYoutubeService(Long pMemberId) throws Exception {
		GoogleOAuthParameters oauthParameters = getOAuthParameters();
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		oauthParameters.setOAuthToken(accessToken.getToken());
		oauthParameters.setOAuthTokenSecret(accessToken.getTokenSecret());

		YouTubeService youtubeService = new YouTubeService(
				GoogleServiceType.YouTube.getGoogleServiceName());
		// Set the OAuth credentials which were obtained from the step
		youtubeService.setOAuthCredentials(oauthParameters, mSigner);
		return youtubeService;
	}

	private <F extends MediaFeed<F, VideoEntry>> F getFeed(YouTubeService pYoutubeService,
			Class<F> pClass) throws Exception {
		URL feedUrl = new URL(GoogleServiceType.YouTube.getFeedUrl());
		return pYoutubeService.getFeed(feedUrl, pClass);
	}

	@Override
	public List<YouTubeVideo> getYoutubeVideos(Long pMemberId) throws Exception {
		YouTubeService service = getYoutubeService(pMemberId);
		VideoFeed feed = getFeed(service, VideoFeed.class);
		List<VideoEntry> entries = feed.getEntries();
		return GoogleYoutubeUtil.convertToVideos(entries);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getApplicationKey
	 * ()
	 */
	@Override
	protected Long getApplicationKey() {
		return youtubeInfoBean.getKey();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oauth.google.server.service.AbstractGoogleOAuthService#
	 * getApplicationService()
	 */
	@Override
	protected ApplicationService getApplicationService() {
		return applicationService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getScope()
	 */
	@Override
	protected String getScope() {
		return GoogleServiceType.YouTube.getScope();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthHelper
	 * ()
	 */
	@Override
	protected GoogleOAuthHelper getOAuthHelper() {
		return mOAuthHelper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthConfigBean
	 * ()
	 */
	@Override
	protected GoogleOAuthConfig getOAuthConfigBean() {
		return oAuthConfigBean;
	}
}
